﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ETModel;

namespace ETHotfix
{
	[ObjectSystem]
	public class ActorMessageDispatherComponentStartSystem: AwakeSystem<ActorMessageDispatherComponent>
	{
		public override void Awake(ActorMessageDispatherComponent self)
		{
			self.Awake();
		}
	}

	[ObjectSystem]
	public class ActorMessageDispatherComponentLoadSystem: LoadSystem<ActorMessageDispatherComponent>
	{
		public override void Load(ActorMessageDispatherComponent self)
		{
			self.Load();
		}
	}

    /// <summary>
    /// ActorMessageDispatherComponent C#扩展语法
    /// </summary>
    public static class ActorMessageDispatherComponentEx
	{
		public static void Awake(this ActorMessageDispatherComponent self)
		{
			self.Load();
		}

        /// <summary>
        /// Awake（）时候会被执行
        /// </summary>
        /// <param name="self"></param>
		public static void Load(this ActorMessageDispatherComponent self)
		{
            //得到服务器类型
			AppType appType = self.Entity.GetComponent<StartConfigComponent>().StartConfig.AppType;

			self.ActorMessageHandlers.Clear(); //清空ActorMessage
            self.ActorTypeHandlers.Clear();   //清空Actor处理函数

            List<Type> types = Game.EventSystem.GetTypes();  //读取程序集

			foreach (Type type in types)  //加载所有的Actor处理函数到字典中
            {
				object[] attrs = type.GetCustomAttributes(typeof(ActorTypeHandlerAttribute), false);
				if (attrs.Length == 0)
				{
					continue;
				}

				ActorTypeHandlerAttribute actorTypeHandlerAttribute = (ActorTypeHandlerAttribute) attrs[0];
				if (!actorTypeHandlerAttribute.Type.Is(appType))  //每个服务器只会加载自身的actor相关类 方法
                {
					continue;
				}

				object obj = Activator.CreateInstance(type);

				IActorTypeHandler iActorTypeHandler = obj as IActorTypeHandler;
				if (iActorTypeHandler == null)
				{
					throw new Exception($"actor handler not inherit IEntityActorHandler: {obj.GetType().FullName}");
				}
                //直接把传参ActorType作为key使用
                self.ActorTypeHandlers.Add(actorTypeHandlerAttribute.ActorType, iActorTypeHandler);
			}

			foreach (Type type in types) //加载所有的Actor消息处理类 到字典中
            {
				object[] attrs = type.GetCustomAttributes(typeof(ActorMessageHandlerAttribute), false);
				if (attrs.Length == 0)
				{
					continue;
				}

				ActorMessageHandlerAttribute messageHandlerAttribute = (ActorMessageHandlerAttribute) attrs[0];
				if (!messageHandlerAttribute.Type.Is(appType))
				{
					continue;
				}

				object obj = Activator.CreateInstance(type);

				IMActorHandler imHandler = obj as IMActorHandler;
				if (imHandler == null)
				{
					throw new Exception($"message handler not inherit IMActorHandler abstract class: {obj.GetType().FullName}");
				}
                
				Type messageType = imHandler.GetMessageType(); //获取消息的类型作为key
				self.ActorMessageHandlers.Add(messageType, imHandler);
			}
		}

        /// <summary>
        /// 如果是封装过的Actor消息  如 ActorMessageInfo  就需要用此函数执行调用对应处理函数
        /// </summary>
        public static async Task ActorTypeHandle(
				this ActorMessageDispatherComponent self, string actorType, Entity entity, ActorMessageInfo actorMessageInfo)
		{
			IActorTypeHandler iActorTypeHandler;
			if (!self.ActorTypeHandlers.TryGetValue(actorType, out iActorTypeHandler))
			{
				throw new Exception($"not found actortype handler: {actorType}");
			}

			await iActorTypeHandler.Handle(actorMessageInfo.Session, entity, actorMessageInfo.Message);
		}

		/// <summary>
		/// 根据actor消息分发给ActorMessageHandler处理
		/// </summary>
		public static async Task Handle(this ActorMessageDispatherComponent self, Session session, Entity entity, IActorMessage actorRequest)
		{
			if (!self.ActorMessageHandlers.TryGetValue(actorRequest.GetType(), out IMActorHandler handler))
			{
				throw new Exception($"not found message handler: {MongoHelper.ToJson(actorRequest)}");
			}

			await handler.Handle(session, entity, actorRequest);
		}
	}
}
